<script lang="ts" setup>
const afterEnter: any = (el: HTMLElement) => {
  el.style.height = 'auto';
};

const enter: any = (el: HTMLElement) => {
  const { width } = getComputedStyle(el);

  el.style.width = width;
  el.style.position = 'absolute';
  el.style.visibility = 'hidden';
  el.style.height = 'auto';

  const { height } = getComputedStyle(el);

  el.style.width = '';
  el.style.position = '';
  el.style.visibility = '';
  el.style.height = '0';

  // 强制重绘以确保正确触发动画。
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  getComputedStyle(el).height;

  requestAnimationFrame(() => {
    el.style.height = height;
  });
};

const leave: any = (el: HTMLElement) => {
  const { height } = getComputedStyle(el);

  el.style.height = height;

  // 强制重绘以确保正确触发动画。
  // eslint-disable-next-line @typescript-eslint/no-unused-expressions
  getComputedStyle(el).height;

  requestAnimationFrame(() => {
    el.style.height = '0';
  });
};
</script>

<template>
  <Transition name="transition-expand" @after-enter="afterEnter" @enter="enter" @leave="leave">
    <slot></slot>
  </Transition>
</template>

<style lang="scss" scoped>
* {
  transform: translateZ(0);
  backface-visibility: hidden;
  perspective: 1000px;
  will-change: height;
}

.transition-expand-enter-active,
.transition-expand-leave-active {
  overflow: hidden;
  opacity: 1;
  transition: height 0.4s, opacity 0.5s;
}

.transition-expand-enter,
.transition-expand-leave-to {
  height: 0;
  opacity: 0;
}
</style>
